package cn.harry.cabinet.arcface.engine

import android.content.Context
import android.util.Log
import cn.harry.cabinet.arcface.util.MemoryMonitor

/**
 * 引擎内存监控工具类
 * 用于监控人脸识别引擎的内存使用情况
 */
class EngineMemoryMonitor private constructor() {
    
    companion object {
        private const val TAG = "EngineMemoryMonitor"
        
        @Volatile
        private var INSTANCE: EngineMemoryMonitor? = null
        
        fun getInstance(): EngineMemoryMonitor {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: EngineMemoryMonitor().also { INSTANCE = it }
            }
        }
    }
    
    private var isMonitoring = false
    
    /**
     * 开始监控引擎内存
     */
    fun startMonitoring(context: Context) {
        if (isMonitoring) {
            Log.d(TAG, "内存监控已在运行中")
            return
        }
        
        try {
            // 使用单例模式的MemoryMonitor
            val memoryMonitor = MemoryMonitor.getInstance()
            
            // 如果已经在监控中，先停止
            if (memoryMonitor.isMonitoring()) {
                Log.d(TAG, "检测到已有内存监控在运行，停止现有监控")
                memoryMonitor.stopMonitoring()
            }
            
            memoryMonitor.startMonitoring(object : MemoryMonitor.MemoryCallback {
                override fun onMemoryWarning(usedMemory: Long, maxMemory: Long, availableMemory: Long) {
                    Log.w(TAG, "引擎内存警告: 可用内存不足150MB，当前可用: ${availableMemory / 1024 / 1024}MB")
                    
                    // 检查引擎状态
                    val engineManager = FaceEngineManager.getInstance()
                    val refCount = engineManager.getReferenceCount()
                    Log.w(TAG, "当前引擎引用计数: $refCount")
                    
                    // 如果引用计数过高，考虑释放一些引用
                    if (refCount > 3) {
                        Log.w(TAG, "引擎引用计数过高，建议检查是否有泄漏")
                    }
                }
                
                override fun onMemoryCritical(usedMemory: Long, maxMemory: Long, availableMemory: Long) {
                    Log.e(TAG, "引擎内存严重警告: 可用内存不足100MB，当前可用: ${availableMemory / 1024 / 1024}MB")
                    
                    // 强制清理引擎资源
                    try {
                        val engineManager = FaceEngineManager.getInstance()
                        if (engineManager.getReferenceCount() > 0) {
                            Log.w(TAG, "内存严重不足，强制销毁引擎")
                            engineManager.forceDestroy()
                        }
                    } catch (e: Exception) {
                        Log.e(TAG, "强制销毁引擎时出错", e)
                    }
                    
                    // 强制垃圾回收
                    memoryMonitor.forceGarbageCollection()
                }
            })
            
            isMonitoring = true
            Log.i(TAG, "引擎内存监控已启动")
            
        } catch (e: Exception) {
            Log.e(TAG, "启动引擎内存监控失败", e)
        }
    }
    
    /**
     * 停止监控
     */
    fun stopMonitoring() {
        try {
            // 注意：这里不直接停止MemoryMonitor，因为它可能被其他地方使用
            // 只是标记本地状态为停止
            isMonitoring = false
            Log.i(TAG, "引擎内存监控已停止")
        } catch (e: Exception) {
            Log.e(TAG, "停止引擎内存监控时出错", e)
        }
    }
    
    /**
     * 记录引擎内存使用情况
     */
    fun logEngineMemoryStatus(operation: String) {
        try {
            val runtime = Runtime.getRuntime()
            val maxMemory = runtime.maxMemory()
            val totalMemory = runtime.totalMemory()
            val freeMemory = runtime.freeMemory()
            val usedMemory = totalMemory - freeMemory
            val availableMemory = maxMemory - usedMemory
            
            val engineManager = FaceEngineManager.getInstance()
            val refCount = engineManager.getReferenceCount()
            val isAvailable = engineManager.isEnginesAvailable()
            
            Log.i(TAG, "=== 引擎内存状态记录 [$operation] ===")
            Log.i(TAG, "最大内存: ${maxMemory / 1024 / 1024}MB")
            Log.i(TAG, "已用内存: ${usedMemory / 1024 / 1024}MB")
            Log.i(TAG, "可用内存: ${availableMemory / 1024 / 1024}MB")
            Log.i(TAG, "引擎引用计数: $refCount")
            Log.i(TAG, "引擎可用状态: $isAvailable")
            Log.i(TAG, "=== 引擎内存状态记录完成 ===")
            
        } catch (e: Exception) {
            Log.e(TAG, "记录引擎内存状态时出错", e)
        }
    }
    
    /**
     * 检查引擎内存健康状态
     */
    fun checkEngineMemoryHealth(): Boolean {
        try {
            val runtime = Runtime.getRuntime()
            val maxMemory = runtime.maxMemory()
            val totalMemory = runtime.totalMemory()
            val freeMemory = runtime.freeMemory()
            val usedMemory = totalMemory - freeMemory
            val availableMemory = maxMemory - usedMemory
            
            val engineManager = FaceEngineManager.getInstance()
            val refCount = engineManager.getReferenceCount()
            
            // 检查内存是否充足
            val hasEnoughMemory = availableMemory > 100 * 1024 * 1024 // 100MB
            
            // 检查引用计数是否合理
            val hasReasonableRefCount = refCount <= 5
            
            // 检查引擎状态
            val isEngineHealthy = engineManager.isEnginesAvailable()
            
            val isHealthy = hasEnoughMemory && hasReasonableRefCount && isEngineHealthy
            
            if (!isHealthy) {
                Log.w(TAG, "引擎内存健康检查失败:")
                Log.w(TAG, "  内存充足: $hasEnoughMemory (可用: ${availableMemory / 1024 / 1024}MB)")
                Log.w(TAG, "  引用计数合理: $hasReasonableRefCount (当前: $refCount)")
                Log.w(TAG, "  引擎状态健康: $isEngineHealthy")
            } else {
                Log.d(TAG, "引擎内存健康检查通过")
            }
            
            return isHealthy
            
        } catch (e: Exception) {
            Log.e(TAG, "检查引擎内存健康状态时出错", e)
            return false
        }
    }
    
    /**
     * 清理资源
     */
    fun destroy() {
        try {
            stopMonitoring()
            Log.i(TAG, "EngineMemoryMonitor已销毁")
        } catch (e: Exception) {
            Log.e(TAG, "销毁EngineMemoryMonitor时出错", e)
        }
    }
} 